package com.jianhua.appmarket.module.service.system.impl;

import com.jianhua.appmarket.common.constant.RoleId;
import com.jianhua.appmarket.common.constant.UserType;
import com.jianhua.appmarket.common.util.AssertBusiness;
import com.jianhua.appmarket.common.util.JWTUtil;
import com.jianhua.appmarket.common.util.SnowflakeKeyUtil;
import com.jianhua.appmarket.common.util.encrypt.EncryptUtils;
import com.jianhua.appmarket.module.dao.system.DeptUserDao;
import com.jianhua.appmarket.module.dao.system.OrgDeptDao;
import com.jianhua.appmarket.module.dao.system.OrgUserDao;
import com.jianhua.appmarket.module.dao.system.RoleUserDao;
import com.jianhua.appmarket.module.dao.system.UserDao;
import com.jianhua.appmarket.module.entity.system.DeptUser;
import com.jianhua.appmarket.module.entity.system.OrgDept;
import com.jianhua.appmarket.module.entity.system.OrgUser;
import com.jianhua.appmarket.module.entity.system.RoleUser;
import com.jianhua.appmarket.module.entity.system.User;
import com.jianhua.appmarket.module.model.system.OrgUserParam;
import com.jianhua.appmarket.module.model.system.UserParam;
import com.jianhua.appmarket.module.model.system.UserVO;
import com.jianhua.appmarket.module.service.system.IUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

@Service
public class UserService implements IUserService {

    @Autowired
    private UserDao userDao;
    @Autowired
    private OrgUserDao orgUserDao;
    @Autowired
    private DeptUserDao deptUserDao;
    @Autowired
    private OrgDeptDao orgDeptDao;
    @Autowired
    private RoleUserDao roleUserDao;

    @Override
    public UserVO login(User user) throws Exception {
        user = userDao.getByParam(user);
        AssertBusiness.isTrue(Objects.nonNull(user),"用户名或密码不正确！");

        UserVO userVO = userDao.getDetailById(user.getId());
        userVO.setNickName(user.getNickName());
        userVO.setPassword(user.getPassword());
        userVO.setToken(JWTUtil.createToken(userVO));
        return userVO;
    }

    @Override
    public User findUserById(Long id) {
        return userDao.getById(id);
    }

    @Override
    public List<UserVO> listUsers(UserParam param,UserVO user) {
        return userDao.listByParam(setUserParam(param,user));
    }

    @Override
    public int countUsers(UserParam param, UserVO user) {
        return userDao.countByParam(setUserParam(param,user));
    }

    private UserParam setUserParam(UserParam param,UserVO user){
        if(Objects.nonNull(param.isByOrgId()) && !param.isByOrgId()){//不是根据组织查询
            if(user.getId() == RoleId.SUPER_ADMIN){//超级管理员查询
                param.setOrgId(null);
                param.setUserType(UserType.COMPANY_ADMIN);
            }
        }else {
            param.setOrgId(Objects.isNull(param.getOrgId()) ? user.getOrgId() : param.getOrgId());
        }
        return param;
    }

    /**
     * 新增用户
     * 1、新增用户表基础信息；
     * 2、新增组织和用户的关系；
     * 3、有部门id的话，则新增部门和用户的关系；
     *
     * 4、新增机构管理员时，角色和用户的关系
     */
    @Override
    @Transactional
    public Boolean addOrEditUser(UserParam userParam, UserVO user) throws Exception {
        User newUser = new User();

        BeanUtils.copyProperties(userParam,newUser);
        if(Objects.isNull(userParam.getId())){
            //判断是否有同登录名的用户
            newUser.setLoginName(userParam.getLoginName());
            AssertBusiness.isTrue(Objects.isNull(userDao.getByParam(newUser)),"该登录名已被使用！");

            addUser(newUser,user);
            addOrgUser(newUser,userParam,user);
            addDeptUser(newUser,userParam,user);
            addRoleUser(newUser,userParam,user);
            return Boolean.TRUE;
        }else {
            return editUser(newUser,user);
        }
    }

    private void addUser(User newUser,UserVO user){
        newUser.setId(SnowflakeKeyUtil.generateId());
        newUser.setCreateUser(user.getNickName());
        newUser.setUpdateUser(user.getNickName());
        newUser.setPassword(EncryptUtils.encryptMD5ToString("123456"));
        userDao.insert(newUser);
    }

    private void addOrgUser(User newUser,UserParam userParam,UserVO user ){
        OrgUser orgUser = new OrgUser();
        orgUser.setId(SnowflakeKeyUtil.generateId());
        orgUser.setUserId(newUser.getId());
        orgUser.setCreateUser(user.getNickName());
        orgUser.setUpdateUser(user.getNickName());

        if(Objects.isNull(userParam.getOrgId())){
            OrgDept orgDept = orgDeptDao.getByDeptId(userParam.getDeptId());
            orgUser.setOrgId(orgDept.getOrgId());
        }else {
            orgUser.setOrgId(userParam.getOrgId());
        }
        orgUserDao.insert(orgUser);
    }

    private void addDeptUser(User newUser,UserParam userParam,UserVO user){
        if(Objects.nonNull(userParam.getDeptId())){
            DeptUser deptUser = new DeptUser();
            deptUser.setId(SnowflakeKeyUtil.generateId());
            deptUser.setDeptId(userParam.getDeptId());
            deptUser.setUserId(newUser.getId());
            deptUser.setCreateUser(user.getNickName());
            deptUserDao.insert(deptUser);
        }
    }

    private void addRoleUser(User newUser,UserParam userParam,UserVO user){
        if(Objects.nonNull(userParam.getUserType()) && userParam.getUserType().equals(UserType.COMPANY_ADMIN)){
            RoleUser roleUser = new RoleUser();
            roleUser.setId(SnowflakeKeyUtil.generateId());
            roleUser.setUserId(newUser.getId());
            roleUser.setRoleId(RoleId.COMPANY_ADMIN);//企业管理员id
            roleUser.setCreateUser(user.getNickName());
            roleUserDao.insert(roleUser);
        }
    }

    @Override
    public Boolean editUser(User newUser, UserVO user) {
        newUser.setUpdateUser(user.getNickName());
        return userDao.update(newUser) > 0;
    }

    @Override
    @Transactional
    public Boolean deleteUser(Long userId, UserVO user) {
        OrgUserParam param = new OrgUserParam();
        param.setOrgId(user.getOrgId());
        param.setUserId(userId);
        return userDao.deleteById(userId) > 0 && orgUserDao.deleteByParam(param) > 0;
    }
}
